<template>
  <div class="code-mirror-form-item">
    <!-- 工具栏 -->
    <div class="toolbar" v-if="showToolbar">
      <a-space>
        <a-button size="small" @click="formatCode" :disabled="!canFormat">
          <a-icon type="bg-colors" />
          格式化
        </a-button>
        <a-button size="small" @click="copyCode">
          <a-icon type="copy" />
          复制
        </a-button>
        <a-button size="small" @click="clearCode">
          <a-icon type="delete" />
          清空
        </a-button>
        <a-select
          v-model="currentLanguage"
          size="small"
          style="width: 120px"
          @change="onLanguageChange"
        >
          <a-select-option v-for="lang in supportedLanguages" :key="lang.value" :value="lang.value">
            {{ lang.label }}
          </a-select-option>
        </a-select>
        <a-select
          v-model="currentTheme"
          size="small"
          style="width: 100px"
          @change="onThemeChange"
        >
          <a-select-option value="light">Light</a-select-option>
          <a-select-option value="dark">Dark</a-select-option>
        </a-select>
      </a-space>
    </div>

    <!-- CodeMirror 编辑器 -->
    <div class="editor-container">
      <codemirror
        v-model="internalValue"
        :style="{ height: editorHeight + 'px' }"
        :options="cmOptions"
        @ready="onReady"
        @input="onChange"
        @focus="onFocus"
        @blur="onBlur"
      />
    </div>

    <!-- 状态栏 -->
    <div class="status-bar" v-if="showStatusBar">
      <span>字符数: {{ characterCount }}</span>
      <span>行数: {{ lineCount }}</span>
      <span v-if="cursorPosition">位置: {{ cursorPosition.line }}:{{ cursorPosition.ch }}</span>
    </div>
  </div>
</template>

<script>
import { codemirror } from 'vue-codemirror'

// CodeMirror 基础样式
import 'codemirror/lib/codemirror.css'

// 主题
import 'codemirror/theme/material.css'
import 'codemirror/theme/base16-dark.css'

// 语言模式
import 'codemirror/mode/javascript/javascript.js'
import 'codemirror/mode/python/python.js'
import 'codemirror/mode/xml/xml.js'
import 'codemirror/mode/css/css.js'
import 'codemirror/mode/sql/sql.js'
import 'codemirror/mode/markdown/markdown.js'

// 插件
import 'codemirror/addon/edit/closebrackets.js'
import 'codemirror/addon/edit/matchbrackets.js'
import 'codemirror/addon/selection/active-line.js'
import 'codemirror/addon/fold/foldcode.js'
import 'codemirror/addon/fold/foldgutter.js'
import 'codemirror/addon/fold/brace-fold.js'
import 'codemirror/addon/fold/comment-fold.js'
import 'codemirror/addon/fold/foldgutter.css'

export default {
  name: 'CodeMirrorFormItem',
  components: {
    codemirror
  },
  props: {
    value: {
      type: String,
      default: ''
    },
    language: {
      type: String,
      default: 'python'
    },
    theme: {
      type: String,
      default: 'light'
    },
    height: {
      type: [Number, String],
      default: 300
    },
    placeholder: {
      type: String,
      default: '请输入代码...'
    },
    disabled: {
      type: Boolean,
      default: false
    },
    autofocus: {
      type: Boolean,
      default: false
    },
    showToolbar: {
      type: Boolean,
      default: true
    },
    showStatusBar: {
      type: Boolean,
      default: true
    }
  },
  data() {
    return {
      editorRef: null,
      internalValue: this.value,
      currentLanguage: this.language,
      currentTheme: this.theme,
      cursorPosition: null,
      supportedLanguages: [
        { label: 'JavaScript', value: 'javascript' },
        { label: 'Python', value: 'python' },
        { label: 'JSON', value: 'application/json' },
        { label: 'HTML', value: 'text/html' },
        { label: 'CSS', value: 'text/css' },
        { label: 'XML', value: 'application/xml' },
        { label: 'SQL', value: 'text/x-sql' },
        { label: 'Markdown', value: 'text/x-markdown' },
        { label: 'Plain Text', value: 'text/plain' }
      ]
    }
  },
  computed: {
    editorHeight() {
      return typeof this.height === 'number' ? this.height : parseInt(this.height)
    },
    characterCount() {
      return this.internalValue.length
    },
    lineCount() {
      return this.internalValue.split('\n').length
    },
    canFormat() {
      return ['javascript', 'application/json', 'text/html', 'text/css'].includes(this.currentLanguage)
    },
    cmOptions() {
      return {
        tabSize: 2,
        mode: this.currentLanguage,
        theme: this.currentTheme === 'dark' ? 'base16-dark' : 'default',
        lineNumbers: true,
        line: true,
        foldGutter: true,
        gutters: ['CodeMirror-linenumbers', 'CodeMirror-foldgutter'],
        styleActiveLine: true,
        matchBrackets: true,
        autoCloseBrackets: true,
        readOnly: this.disabled,
        autofocus: this.autofocus,
        placeholder: this.placeholder,
        lineWrapping: true
      }
    }
  },
  watch: {
    value(newValue) {
      if (newValue !== this.internalValue) {
        this.internalValue = newValue
      }
    },
    language(newLanguage) {
      this.currentLanguage = newLanguage
    },
    theme(newTheme) {
      this.currentTheme = newTheme
    }
  },
  methods: {
    onChange(value) {
      this.internalValue = value
      this.$emit('input', value)
      this.$emit('change', value)

      // 更新光标位置
      if (this.editorRef) {
        const cursor = this.editorRef.getCursor()
        this.cursorPosition = {
          line: cursor.line + 1,
          ch: cursor.ch + 1
        }
      }
    },
    onFocus(editor, event) {
      this.$emit('focus', editor, event)
    },
    onBlur(editor, event) {
      this.$emit('blur', editor, event)
    },
    onReady(editor) {
      this.editorRef = editor
      this.$emit('ready', editor)

      // 监听光标位置变化
      editor.on('cursorActivity', () => {
        const cursor = editor.getCursor()
        this.cursorPosition = {
          line: cursor.line + 1,
          ch: cursor.ch + 1
        }
      })
    },
    formatCode() {
      if (!this.editorRef || !this.canFormat) return

      try {
        let formatted = this.internalValue

        if (this.currentLanguage === 'application/json') {
          formatted = JSON.stringify(JSON.parse(this.internalValue), null, 2)
        } else if (this.currentLanguage === 'javascript') {
          // 简单的 JavaScript 格式化
          formatted = this.internalValue
            .replace(/;\s*/g, ';\n')
            .replace(/{\s*/g, '{\n  ')
            .replace(/}\s*/g, '\n}')
            .replace(/,\s*/g, ',\n  ')
        }

        this.internalValue = formatted
        this.$emit('input', formatted)
        this.editorRef.setValue(formatted)
      } catch (error) {
        console.error('格式化失败:', error)
        this.$message.error('代码格式化失败，请检查语法')
      }
    },
    async copyCode() {
      try {
        if (navigator.clipboard) {
          await navigator.clipboard.writeText(this.internalValue)
        } else {
          // 兼容旧浏览器
          const textArea = document.createElement('textarea')
          textArea.value = this.internalValue
          document.body.appendChild(textArea)
          textArea.select()
          document.execCommand('copy')
          document.body.removeChild(textArea)
        }
        this.$message.success('代码已复制到剪贴板')
      } catch (error) {
        console.error('复制失败:', error)
        this.$message.error('复制失败')
      }
    },
    clearCode() {
      this.internalValue = ''
      this.$emit('input', '')
      if (this.editorRef) {
        this.editorRef.setValue('')
      }
    },
    onLanguageChange(language) {
      this.currentLanguage = language
      if (this.editorRef) {
        this.editorRef.setOption('mode', language)
      }
    },
    onThemeChange(theme) {
      this.currentTheme = theme
      if (this.editorRef) {
        this.editorRef.setOption('theme', theme === 'dark' ? 'base16-dark' : 'default')
      }
    },
    // 公开方法
    getFormData() {
      return this.internalValue
    },
    setFormData(value) {
      this.internalValue = value
      this.$emit('input', value)
      if (this.editorRef) {
        this.editorRef.setValue(value)
      }
    },
    resetForm() {
      this.internalValue = ''
      this.$emit('input', '')
      if (this.editorRef) {
        this.editorRef.setValue('')
      }
    },
    focus() {
      if (this.editorRef) {
        this.editorRef.focus()
      }
    }
  }
}
</script>

<style scoped>
.code-mirror-form-item {
  border: 1px solid #d9d9d9;
  border-radius: 6px;
  overflow: hidden;
  transition: border-color 0.3s;
}

.code-mirror-form-item:hover {
  border-color: #40a9ff;
}

.code-mirror-form-item:focus-within {
  border-color: #1890ff;
  box-shadow: 0 0 0 2px rgba(24, 144, 255, 0.2);
}

.toolbar {
  padding: 8px 12px;
  background-color: #fafafa;
  border-bottom: 1px solid #d9d9d9;
  display: flex;
  align-items: center;
  justify-content: space-between;
}

.editor-container {
  position: relative;
  .vue-codemirror {
    overflow-y: auto;
  }
}

.editor-container >>> .CodeMirror {
  height: auto;
  min-height: 200px;
  font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;
  font-size: 14px;
}

.editor-container >>> .CodeMirror-scroll {
  min-height: 200px;
}

.status-bar {
  padding: 4px 12px;
  background-color: #fafafa;
  border-top: 1px solid #d9d9d9;
  font-size: 12px;
  color: #666;
  display: flex;
  gap: 16px;
}

/* 深色主题样式 */
.code-mirror-form-item.dark {
  border-color: #434343;
}

.code-mirror-form-item.dark .toolbar,
.code-mirror-form-item.dark .status-bar {
  background-color: #1e1e1e;
  border-color: #434343;
  color: #cccccc;
}

/* 响应式设计 */
@media (max-width: 768px) {
  .toolbar {
    flex-direction: column;
    gap: 8px;
    align-items: stretch;
  }

  .status-bar {
    flex-direction: column;
    gap: 4px;
  }
}
</style>
